package com.dimples.wxpush.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.extra.servlet.ServletUtil;
import com.dimples.wxpush.constant.QiYeWxConfigConstant;
import com.dimples.wxpush.utils.aes.WXBizMsgCrypt;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import javax.servlet.http.HttpServletRequest;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.StringReader;

/**
 * @author zhongyj <1126834403@qq.com><br/>
 * @date 2024/11/15
 */
@Slf4j
@RestController
@RequestMapping("callable")
@RequiredArgsConstructor
public class CallableController {

    private final QiYeWxConfigConstant qiYeWxConfigConstant;

    @GetMapping("qywx")
    public String qyWxGetCallable(
            @RequestParam("msg_signature") String sVerifyMsgSig,
            @RequestParam("timestamp") String sVerifyTimeStamp,
            @RequestParam("nonce") String sVerifyNonce,
            @RequestParam("echostr") String sVerifyEchoStr
    ) {
        //需要返回的明文
        String sEchoStr = "";
        try {
            WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(qiYeWxConfigConstant.getCallableToken(), qiYeWxConfigConstant.getCallableEncodingAesKey(), qiYeWxConfigConstant.getCorpid());
            sEchoStr = wxcpt.VerifyURL(sVerifyMsgSig, sVerifyTimeStamp, sVerifyNonce, sVerifyEchoStr);
            log.info("verify-url echo-str: {}", sEchoStr);
        } catch (Exception e) {
            //验证URL失败，错误原因请查看异常
            log.error("verify-url error: {}", ExceptionUtil.stacktraceToString(e));
        }
        return sEchoStr;
    }

    @PostMapping("qywx")
    public String qyWxPostCallable(
            @RequestParam("msg_signature") String sReqMsgSig,
            @RequestParam("timestamp") String sReqTimeStamp,
            @RequestParam("nonce") String sReqNonce,
            HttpServletRequest request
    ) {
        String sReqData = ServletUtil.getBody(request);

        try {
            WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(qiYeWxConfigConstant.getCallableToken(), qiYeWxConfigConstant.getCallableEncodingAesKey(), qiYeWxConfigConstant.getCorpid());

            String sMsg = wxcpt.DecryptMsg(sReqMsgSig, sReqTimeStamp, sReqNonce, sReqData);
            log.info("after decrypt msg: {}", sMsg);

            // 解析出明文xml标签的内容进行处理
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            StringReader sr = new StringReader(sMsg);
            InputSource is = new InputSource(sr);
            Document document = db.parse(is);

            Element root = document.getDocumentElement();
            NodeList contentList = root.getElementsByTagName("Content");
            String Content = contentList.item(0).getTextContent();

            log.info("Content: {}", Content);
        } catch (Exception e) {
            //验证URL失败，错误原因请查看异常
            log.error("verify-url error: {}", ExceptionUtil.stacktraceToString(e));
        }

        String sRespData = "<xml>" +
                "<ToUserName><![CDATA[" + qiYeWxConfigConstant.getCorpid() + "]]></ToUserName>" +
                "<FromUserName><![CDATA[" + qiYeWxConfigConstant.getCorpid() + "]]></FromUserName>" +
                "<CreateTime>" + DateUtil.date().getTime() + "</CreateTime>" +
                "<MsgType><![CDATA[text]]></MsgType>" +
                "<Content><![CDATA[" + "success" + "]]></Content>" +
                "<MsgId>" + IdUtil.getSnowflakeNextIdStr() + "</MsgId>" +
                "<AgentID>" + qiYeWxConfigConstant.getAgentId() + "</AgentID>" +
                "</xml>";
        try {
            WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(qiYeWxConfigConstant.getCallableToken(), qiYeWxConfigConstant.getCallableEncodingAesKey(), qiYeWxConfigConstant.getCorpid());
            String sEncryptMsg = wxcpt.EncryptMsg(sRespData, sReqTimeStamp, sReqNonce);
            System.out.println("after encrypt encryptMsg: " + sEncryptMsg);
            // 加密成功
            return sEncryptMsg;
        } catch (Exception e) {
            log.error("encrypt error: {}", ExceptionUtil.stacktraceToString(e));
        }
        return "";
    }

}
























